﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DialogActivationBehavior.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the <seealso cref="DialogActivationBehavior" /> type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Common.Helpers
{
    using System.Collections.Specialized;
    using System.Windows;

    using Microsoft.Practices.Prism.Regions;
    using Microsoft.Practices.Prism.Regions.Behaviors;

    /// <summary>
    /// Defines the <seealso cref="DialogActivationBehavior"/> type.
    /// </summary>
    public abstract class DialogActivationBehavior : RegionBehavior, IHostAwareRegionBehavior
    {
        /// <summary>
        /// The key of this behavior
        /// </summary>
        public const string BehaviorKey = "DialogActivation";

        /// <summary>
        /// Member variable contentDialog
        /// </summary>
        private IWindow _contentDialog;

        /// <summary>
        /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
        /// </summary>
        /// <value>A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
        /// This is usually a <see cref="FrameworkElement"/> that is part of the tree.</value>
        public DependencyObject HostControl { get; set; }

        /// <summary>
        /// Performs the logic after the behavior has been attached.
        /// </summary>
        protected override void OnAttach()
        {
            Region.ActiveViews.CollectionChanged += OnActiveViewsCollectionChanged;
        }

        /// <summary>
        /// Override this method to create an instance of the <see cref="IWindow"/> that
        /// will be shown when a view is activated.
        /// </summary>
        /// <returns>
        /// An instance of <see cref="IWindow"/> that will be shown when a
        /// view is activated on the target <see cref="IRegion"/>.
        /// </returns>
        protected abstract IWindow CreateWindow();

        /// <summary>
        /// Handles the CollectionChanged event of the ActiveViews control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        private void OnActiveViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                CloseContentDialog();
                PrepareContentDialog(e.NewItems[0]);
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                CloseContentDialog();
            }
        }

        /// <summary>
        /// Gets the style for view.
        /// </summary>
        /// <returns>Style for view</returns>
        private Style GetStyleForView()
        {
            return HostControl.GetValue(RegionPopupBehaviors.ContainerWindowStyleProperty) as Style;
        }

        /// <summary>
        /// Prepares the content dialog.
        /// </summary>
        /// <param name="view">The view.</param>
        private void PrepareContentDialog(object view)
        {
            _contentDialog = CreateWindow();
            _contentDialog.Content = view;
            _contentDialog.Owner = HostControl;
            _contentDialog.Closed += ContentDialogClosed;
            _contentDialog.Style = GetStyleForView();
            _contentDialog.Show();
        }

        /// <summary>
        /// Closes the content dialog.
        /// </summary>
        private void CloseContentDialog()
        {
            if (_contentDialog != null)
            {
                _contentDialog.Closed -= ContentDialogClosed;
                _contentDialog.Close();
                _contentDialog.Content = null;
                _contentDialog.Owner = null;
            }
        }

        /// <summary>
        /// Contents the dialog closed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void ContentDialogClosed(object sender, System.EventArgs e)
        {
            Region.Deactivate(_contentDialog.Content);
            CloseContentDialog();
        }
    }
}